package com.common.service.departmentjob.impl;

import com.common.converter.JobConverter;
import com.common.entity.department.DepartmentEntity;
import com.common.entity.department.QDepartmentEntity;
import com.common.entity.job.JobEntity;
import com.common.entity.job.QJobEntity;
import com.common.global.BizException;
import com.common.global.CommonEnum;
import com.common.query.QueryConditionVo;
import com.common.repository.departmentjob.DepartmentRepository;
import com.common.repository.departmentjob.JobRepository;
import com.common.requestvo.departmentjob.DepartmentReqVo;
import com.common.requestvo.departmentjob.JobReqVo;
import com.common.service.departmentjob.DepartmentService;
import com.common.service.departmentjob.JobService;
import com.common.vo.departmentjob.DepartmentVo;
import com.common.vo.departmentjob.JobVo;
import com.querydsl.core.QueryResults;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;

/**
 * @author johnny
 * @create 2021-05-14 9:04 下午
 **/
@Service
@Slf4j
@Transactional(rollbackOn = Exception.class)
public class JobServiceImpl implements JobService {
    private final JPAQueryFactory queryFactory;

    private final JobRepository jobRepository;

    public JobServiceImpl(JPAQueryFactory queryFactory, JobRepository jobRepository) {
        this.queryFactory = queryFactory;
        this.jobRepository = jobRepository;
    }

    @Override
    public Page<JobVo> listByCondition(JobReqVo jobReqVo, Pageable pageable) {
        List<JobVo> list = new ArrayList<>();
        QJobEntity qJobEntity = QJobEntity.jobEntity;

        JPAQuery<JobEntity> jpaQuery = queryFactory.selectFrom(qJobEntity)
                .offset(pageable.getPageNumber() * pageable.getPageSize())
                .limit(pageable.getPageSize());

        fillCondition(jpaQuery, jobReqVo);
        QueryResults<JobEntity> queryResults = jpaQuery.fetchResults();

        queryResults.getResults().forEach(jobEntity -> {
            JobVo jobVo = JobConverter.INSTANCE.domain2vo(jobEntity);
            list.add(jobVo);
        });
        return new PageImpl<>(list, pageable, queryResults.getTotal());
    }

    @Override
    public void add(JobReqVo jobReqVo) {
        jobReqVo.setId(null);
        Long count = jobRepository.countByJobName(jobReqVo.getJobName());
        if (count == 0) {
            JobEntity jobEntity = JobConverter.INSTANCE.vo2domain(jobReqVo);
            jobRepository.save(jobEntity);
        }
    }

    @Override
    public void edit(JobReqVo jobReqVo) {
        if (jobReqVo.getId() != null && jobReqVo.getId() != 0L) {
            if (jobRepository.existsById(jobReqVo.getId())) {
                JobEntity jobEntity = JobConverter.INSTANCE.vo2domain(jobReqVo);
                jobRepository.save(jobEntity);
            } else {
                throw new BizException(CommonEnum.ID_NOT_FIND_ENTITY);
            }
        } else {
            throw new BizException(CommonEnum.ID_NOT_NULL);
        }
    }

    @Override
    public void delete(Long id) {
        if (jobRepository.existsById(id)) {
            jobRepository.deleteById(id);
        } else {
            throw new BizException(CommonEnum.ID_NOT_FIND_ENTITY);
        }
    }

    @Override
    public void fillCondition(JPAQuery<JobEntity> jpaQuery, QueryConditionVo queryConditionVo) {
        QJobEntity qJobEntity = QJobEntity.jobEntity;

        JobReqVo jobReqVo = (JobReqVo) queryConditionVo;
        if (StringUtils.isNotEmpty(jobReqVo.getJobName())) {
            jpaQuery.where(qJobEntity.jobName.like("%" + jobReqVo.getJobName() + "%"));
        }
    }
}